# from sklearn.datasets import load_boston
from sklearn.linear_model import LinearRegression, SGDRegressor,Ridge,LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.model_selection import cross_val_predict
from sklearn.model_selection import cross_val_score
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import mean_squared_error
from sklearn import preprocessing
from sklearn.metrics import mean_squared_error, r2_score
import pandas as pd
import os
import csv
import numpy as np
import matplotlib.pyplot as plt


# Window系统下设置字体为SimHei
plt.rcParams['font.sans-serif'] = ['SimHei']
# Mac系统下设置字体为Arial Unicode MS
# plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']


def testHouse_temp():
    from pandas import set_option
    from matplotlib import pyplot
    from pandas.plotting import scatter_matrix
    # 读取房屋数据集
    data = pd.read_csv('./data/homeA_Z.csv')
    # 通过 head 方法查看数据集的前几行数据
    set_option('display.column_space', 120)
    # print(df.head())

    # 数据维度
    print(data.shape)

    # 特征属性的字段类型
    # print(data.dtypes)

    #检查有没有数据中有没有空值
    print(data.isnull().any().sum())

    # 描述性统计信息
    # set_option('precision', 1)
    # print(data.describe())

    #提取特征和标记
    prices = data['temperature']
    features = data.drop('temperature', axis=1)

    #关联关系
    set_option('precision', 2)
    print(data.corr(method='pearson'))

    #直方图
    data.hist(sharex=False, sharey=False, xlabelsize=1, ylabelsize=1)
    pyplot.show()

    #密度图
    data.plot(kind='density', subplots=True, layout=(4, 4), sharex=False, fontsize=1)
    pyplot.show()

    #箱线图
    data.plot(kind='box', subplots=True, layout=(4, 4), sharex=False, sharey=False, fontsize=8)
    pyplot.show()

    # 查看各个特征的散点分布
    scatter_matrix(data, alpha=0.7, figsize=(10, 10), diagonal='kde')
    pyplot.show()


    # Heatmap


# 绘图函数
def figure(title, *datalist):
    plt.figure(facecolor='gray', figsize=[8, 4])
    for v in datalist:
        plt.plot(v[0], '-', label=v[1], linewidth=2)
        plt.plot(v[0], 'o')
    plt.grid()
    plt.title(title, fontsize=20)
    plt.legend(fontsize=16)
    plt.show()


def mylinear():
    """
    线性回归直接预测房价
    :return: None
    """
    data = pd.read_csv('./data/homeA_Z.csv')

    #print(data)
    x = data[['humidity', 'visibility', 'apparentTemperature', 'pressure', 'windSpeed', 'cloudCover', 'windBearing', 'precipIntensity',
              'dewPoint','precipProbability']]

    # print(x.head())
    y = data['temperature']
    # 分割训练集和测试集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.20)
    print('训练集和测试集',x_train.shape, x_test.shape, y_train.shape, y_test.shape)



    # 初始化标准化器
    min_max_scaler = preprocessing.MinMaxScaler()
    # 分别对训练和测试数据的特征以及目标值进行标准化处理
    x_train = min_max_scaler.fit_transform(x_train)
    y_train = min_max_scaler.fit_transform(y_train.values.reshape(-1, 1))  # reshape(-1,1)指将它转化为1列，行自动确定
    x_test = min_max_scaler.fit_transform(x_test)
    y_test = min_max_scaler.fit_transform(y_test.values.reshape(-1, 1))

    #print('训练集和测试集', x_train.shape, x_test.shape, y_train.shape, y_test.shape)


    # 方法一 线性回归
    lr = LinearRegression()
    # 使用训练数据进行参数估计
    lr.fit(x_train, y_train)
    # 使用测试数据进行回归预测
    y_test_pred = lr.predict(x_test)
    print(y_test_pred)
    # 训练数据的预测值
    y_train_pred = lr.predict(x_train)
    # 计算均方差
    train_error = [mean_squared_error(y_train, [np.mean(y_train)] * len(y_train)),
                   mean_squared_error(y_train, y_train_pred)]
    # 绘制误差图
    figure('误差图 最终的MSE = %.4f' % (train_error[-1]), [train_error, 'Error'])

    # 绘制预测值与真实值图
    figure('预测值与真实值图 模型的' + r'$R^2=%.4f$' % (r2_score(y_train_pred, y_train)), [y_test_pred, '预测值'],
           [y_test, '真实值'])

    # 线性回归的系数
    print('线性回归的系数为:\n w = %s \n b = %s' % (lr.coef_, lr.intercept_))

    lr = LinearRegression()
    lr_predict = cross_val_predict(lr, x_train, y_train, cv=5)

    lr_score = cross_val_score(lr, x_train, y_train, cv=5)
    lr_meanscore = lr_score.mean()
    print(lr_score)
    print(lr_meanscore)


    return None


def mylinear_2():
    """
    线性回归直接预测房价
    :return: None
    """
    # 获取数据

    data = pd.read_csv('./data/homeA_Z.csv')

    #print(data)
    x = data[['humidity', 'visibility', 'apparentTemperature', 'pressure', 'windSpeed', 'cloudCover', 'windBearing', 'precipIntensity',
              'dewPoint','precipProbability']]

    # print(x.head())
    y = data['temperature']
    # 分割训练集和测试集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.20,random_state=1)
    print('训练集和测试集',x_train.shape, x_test.shape, y_train.shape, y_test.shape)


    # 进行标准化处理
    # 特征值和目标值都需要进行标准化处理，因为特征值和目标值特证数不同，所以需要实例化两个标准化API
    std_x = StandardScaler()
    x_train = std_x.fit_transform(x_train)
    x_test = std_x.transform(x_test)

    # 目标值
    std_y = StandardScaler()
    y_train = std_y.fit_transform(y_train.values.reshape(-1, 1))  # 0.19版本以后要求是二维，不知道样本数，所以-1，一个特征所以1
    y_test = std_y.transform(y_test.values.reshape(-1, 1))

    # 线性回归预测
    lr = LinearRegression()
    lr.fit(x_train, y_train)
    print("线性回归系数：", lr.coef_)
    #y_predict=lr.predict(x_test)
    y_predict = std_y.inverse_transform(lr.predict(x_test))
    y_predict_train= std_y.inverse_transform(lr.predict(x_train))
    print("线性回归_准确率：", lr.score(x_test, y_test))  # 准确率
    print("线性回归的R-Square（决定系数)：", mean_squared_error(std_y.inverse_transform(y_test), y_predict))
    print("线性回归测试集里的预测温度：", y_predict)
    #mean_squared_error


    # from sklearn import metrics
    # n_class = len(data['accept'].unique())  # accept是标签列
    # y_test_one_hot = label_binarize(y_test, classes=np.arange(n_class))  # 将标签值映射成one-hot编码
    #
    # y_test_one_hot_hat = y_predict  # 测试集预测分类概率
    # fpr, tpr, _ = metrics.roc_curve(y_test_one_hot.ravel(), y_test_one_hot_hat.ravel())
    # print('Micro AUC:\t', metrics.auc(fpr, tpr))  # AUC ROC意思是ROC曲线下方的面积(Area under the Curve of ROC)
    # print('Micro AUC(System):\t', metrics.roc_auc_score(y_test_one_hot, y_test_one_hot_hat, average='micro'))
    #
    # auc = metrics.roc_auc_score(y_test_one_hot, y_test_one_hot_hat, average='macro')
    # print('Macro AUC:\t', auc)

    # 均方误差（MSE）

    # 残差评估方法
    plt.scatter(y_predict_train, y_predict_train - y_train,
                c='blue', marker='o', label='Training data')
    plt.scatter(y_predict, y_predict - y_test,
                c='lightgreen', marker='s', label='Test data')
    plt.xlabel('Predicted values')
    plt.ylabel('Residuals')
    plt.legend(loc='upper left')
    plt.hlines(y=0, xmin=-10, xmax=50, lw=2, colors='red')
    plt.xlim([-10, 50])
    #plt.savefig('residuals_metric.png')
    plt.show()






    # 梯度下降求解方式预测结果
    sgd = SGDRegressor()

    sgd.fit(x_train, y_train.ravel())
    print("梯度下降回归系数：", sgd.coef_)

    # 预测的房价
    y_sgd_predict = std_y.inverse_transform(sgd.predict(x_test))
    print("SGDRegressor_准确率：", sgd.score(x_test, y_test))  # 准确率
    print("梯度下降测试集里的预测温度：\n", y_sgd_predict)
    print("梯度下降的R-Square（决定系数)：", mean_squared_error(std_y.inverse_transform(y_test), y_sgd_predict))

    return None


def mylinear_3():
    """
    正规方程求解方式
    :return: None
    """
    data = pd.read_csv('./data/homeA_Z.csv')

    #print(data)
    x = data[['humidity', 'visibility', 'apparentTemperature', 'pressure', 'windSpeed', 'cloudCover', 'windBearing', 'precipIntensity',
              'dewPoint','precipProbability']]

    # print(x.head())
    y = data['temperature']
    # 分割训练集和测试集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.20,random_state=1)
    print('训练集和测试集',x_train.shape, x_test.shape, y_train.shape, y_test.shape)

    # 进行标准化处理
    # 特征值和目标值都需要进行标准化处理，因为特征值和目标值特证数不同，所以需要实例化两个标准化API
    std_x = StandardScaler()
    x_train = std_x.fit_transform(x_train)
    x_test = std_x.transform(x_test)

    # 目标值
    std_y = StandardScaler()
    y_train = std_y.fit_transform(y_train.values.reshape(-1, 1))  # 0.19版本以后要求是二维，不知道样本数，所以-1，一个特征所以1
    y_test = std_y.transform(y_test.values.reshape(-1, 1))

    # estimstor预测
    # 正规方程求解方式预测结果
    rg = Ridge()
    rg.fit(x_train, y_train)
    print("正规方程回归系数：", rg.coef_)

    # 预测的房价
    y_predict = std_y.inverse_transform(rg.predict(x_test))
    y_predict_train = std_y.inverse_transform(rg.predict(x_train))
    print("正规方程_准确率：", rg.score(x_test, y_test))  # 准确率
    print("正规方程测试集的预测温度：", y_predict)
    print("正规方程的R-Square（决定系数)：", mean_squared_error(std_y.inverse_transform(y_test), y_predict))

    plt.scatter(y_predict_train, y_predict_train - y_train,
                c='blue', marker='o', label='Training data')
    plt.scatter(y_predict, y_predict - y_test,
                c='lightgreen', marker='s', label='Test data')
    plt.xlabel('Predicted values')
    plt.ylabel('Residuals')
    plt.legend(loc='upper left')
    plt.hlines(y=0, xmin=-10, xmax=50, lw=2, colors='red')
    plt.xlim([-10, 50])
    #plt.savefig('residuals_metric.png')
    plt.show()

def Logistic_Reg():  #逻辑回归
    """
    正规方程求解方式
    :return: None
    """
    data = pd.read_csv('./data/homeA_Z.csv')

    #print(data)
    x = data[['humidity', 'visibility', 'apparentTemperature', 'pressure', 'windSpeed', 'cloudCover', 'windBearing', 'precipIntensity',
              'dewPoint','precipProbability']]

    # print(x.head())
    y = data['temperature']
    # 分割训练集和测试集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.10)
    print('训练集和测试集',x_train.shape, x_test.shape, y_train.shape, y_test.shape)

    lr = LogisticRegression()  # 调用逻辑回归
    lr.fit(x_train, y_train)  # 用测试集训练模型
    print(lr.coef_)  # 系数
    y_predict = lr.predict(x_test)  # 预测
    print("准确率：", lr.score(x_test, y_test))  # 准确率
    print("",y_predict)

def KNN_room_tempe():
    """
    正规方程求解方式
    :return: None
    """
    data = pd.read_csv('./data/homeA_Z.csv')

    #print(data)
    x = data[['humidity', 'visibility', 'apparentTemperature', 'pressure', 'windSpeed', 'cloudCover', 'windBearing', 'precipIntensity',
              'dewPoint','precipProbability']]

    # print(x.head())
    y = data['temperature']
    # 分割训练集和测试集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.20,random_state=1)
    print('训练集和测试集',x_train.shape, x_test.shape, y_train.shape, y_test.shape)

    from sklearn.neighbors import KNeighborsRegressor
    from sklearn.model_selection import cross_val_predict
    from sklearn.model_selection import cross_val_score
    score = []
    # for n_neighbors in range(1, 36):
    #     knn = KNeighborsRegressor(n_neighbors, weights='uniform')
    #     knn_predict = cross_val_predict(knn, x_train, y_train, cv=5)
    #     print(knn_predict)
    #     knn_score = cross_val_score(knn, x_train, y_train, cv=5)
    #     knn_meanscore = knn_score.mean()
    #     score.append(knn_meanscore)
    #     print("KNN近邻_准确率：", knn_score)
    # plt.plot(score)
    # plt.xlabel('n-neighbors')
    # plt.ylabel('mean-score')
    # plt.show()


    knn = KNeighborsRegressor(2, weights='uniform')
    knn_predict = cross_val_predict(knn, x_train, y_train, cv=5)
    knn_score = cross_val_score(knn, x_train, y_train, cv=5)
    knn_meanscore = knn_score.mean()

    print("KNN近邻_准确率：", knn_score)
    print("KNN近邻的预测温度：",knn_predict)
    print("KNN近邻_的均值：", knn_meanscore)


def Decision_Tree():
    """
    正规方程求解方式
    :return: None
    """
    data = pd.read_csv('./data/homeA_Z.csv')

    #print(data)
    x = data[['humidity', 'visibility', 'apparentTemperature', 'pressure', 'windSpeed', 'cloudCover', 'windBearing', 'precipIntensity',
              'dewPoint','precipProbability']]

    # print(x.head())
    y = data['temperature']
    # 分割训练集和测试集
    x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.20,random_state=1)
    print('训练集和测试集',x_train.shape, x_test.shape, y_train.shape, y_test.shape)

    from sklearn.tree import DecisionTreeRegressor
    score = []
    for n in range(1, 11):
        dtr = DecisionTreeRegressor(max_depth=n)
        dtr_predict = cross_val_predict(dtr, x_train, y_train, cv=5)
        dtr_score = cross_val_score(dtr, x_train, y_train, cv=5)
        dtr_meanscore = dtr_score.mean()
        score.append(dtr_meanscore)
    plt.plot(np.linspace(1, 10, 10), score)
    plt.xlabel('max_depth')
    plt.ylabel('mean-score')
    plt.show()

    dtr = DecisionTreeRegressor(max_depth=4)
    dtr_predict = cross_val_predict(dtr, x_train, y_train, cv=5)
    dtr_score = cross_val_score(dtr, x_train, y_train, cv=5)
    dtr_meanscore = dtr_score.mean()
    print("决策树_准确率：", dtr_score)
    print("决策树的预测温度：",dtr_predict)
    print("决策树_的均值：", dtr_meanscore)

if __name__ == '__main__':

    # testHouse_temp()   # 数据分析 ，直方图，箱型图，散点图等
    #  mylinear_2()      # 线性回归预测  和 梯度下降
    #  mylinear_3()      # 正规方程求解方式预测结果
    #  KNN_room_tempe()  # knn
     Decision_Tree()   # 决策树

